/**
 * 作者: wgx
 * 日期: 2025-05-06 16:24:38
 * 备注: 用户大世界的行军队列
 */
package com.motu.monstercity.server.game.userdata;

import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.Common.PBUserWorldTeam;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.bag.ItemId;
import com.motu.monstercity.server.game.commondata.skill.SkillConstant;
import com.motu.monstercity.server.game.commondata.world.WorldConstant;
import com.motu.monstercity.server.game.commondata.world.WorldEvent;
import com.motu.monstercity.server.game.logic.*;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonObject;

import java.util.List;



public class UserWorldTeam extends UserWorldTeamModel {
    public UserWorldTeam() {
        super();
    }

    public UserWorldTeam(JsonObject obj) {
        teamId = obj.containsKey("team_id") ? obj.getInteger("team_id") : 0;
        status = obj.containsKey("status") ? obj.getInteger("status") : 0;
        locationId = obj.containsKey("location_id") ? obj.getInteger("location_id") : 0;
        startTime = obj.containsKey("start_time") ? obj.getLong("start_time") : 0;
        partner = obj.containsKey("partner") ? obj.getString("partner") : "";
        soldier = obj.containsKey("soldier") ? obj.getInteger("soldier") : 0;
        power = obj.containsKey("power") ? obj.getLong("power") : 0;
        timeLeft = obj.containsKey("time_left") ? obj.getInteger("time_left") : 0;
        updateTime = obj.containsKey("update_time") ? obj.getLong("update_time") : 0;
        eventId = obj.containsKey("event_id") ? obj.getInteger("event_id") : 0;
        onewayTime = obj.containsKey("oneway_time") ? obj.getInteger("oneway_time") : 0;
        coordX = obj.containsKey("coord_x") ? obj.getInteger("coord_x") : 0;
        coordY = obj.containsKey("coord_y") ? obj.getInteger("coord_y") : 0;
        reduceTime = obj.containsKey("reduce_time") ? obj.getInteger("reduce_time") : 0;
        uniqeId = obj.containsKey("uniqe_id") ? obj.getString("uniqe_id") : "";
        param = obj.containsKey("param") ? obj.getString("param") : "";
        validTime = obj.containsKey("valid_time") ? obj.getLong("valid_time") : 0;
    }


    // 清除数据,重置到初始状态
    public void cleanData() {
        putStatus(WorldConstant.WORLD_TEAM_STATUS_0);
        putLocationId(0);
        putStartTime(0L);
        putPartner("");
        putSoldier(0);
        putPower(0L);
        putTimeLeft(0);
        putUpdateTime(0L);
        putEventId(0);
        putForces(0L);
        putResult(0);
        putOnewayTime(0);
        putCoordX(0);
        putCoordY(0);
        putHelpDbid(0L);
        putReduceTime(0);
        putUniqeId("");
        putTotalForces(0L);
        putRandomReward("");
        putBoxReward("");
        putParam("");
    }

    // 刷新队伍信息
    public void refreshData(PBUserData.Builder pbUserData, UserInfo userInfo, UserWorldInfo userWorldInfo) {
        if (getStatus() == WorldConstant.WORLD_TEAM_STATUS_0) {
            return;
        }
        long curTime = TimeUtils.getCurTime();
        long diffTime = TimeUtils.getTimeDiff(getUpdateTime());// 距离上次结算已经过去的时间

        if (diffTime + getReduceTime() < getTimeLeft()) {//未完成单程的时间
            long newTimeLfet = getTimeLeft() - diffTime - getReduceTime();
            putTimeLeft((int) newTimeLfet);
            putReduceTime(0);
            putUpdateTime(curTime);
        } else {// 超过单程的剩余时间
            int oldStatus = getStatus();// 原本的行军状态
            if (oldStatus == WorldConstant.WORLD_TEAM_STATUS_2) {// 原本是返回途中，或是溢出的时间超过单程时间，可以回到基地，更新为返回基地的状态
                WorldManager.handleTeamComplete(pbUserData, userInfo, this);
            } else if (oldStatus == WorldConstant.WORLD_TEAM_STATUS_1) {// 出征途中，到达了位置，完成事件
                int totalTime = getTimeLeft() + WorldManager.takeReturnTime(getOnewayTime());// 到达事件地点，且返回基地总的需要耗时多少
                UserWorldEventLocation userWorldEventLocation = WorldManager.getUserWorldEventLocation(userInfo.getId(), getLocationId());
                WorldManager.handleTeamArrive(pbUserData, userInfo, userWorldInfo, this, userWorldEventLocation, false);
                userWorldEventLocation.update();
                if (diffTime >= totalTime) {// 玩家的自然耗时足够返回基地
                    WorldManager.handleTeamComplete(pbUserData, userInfo, this);
                }
            }
        }

    }

    // 计算战斗结果 <当前战力，失败， >= 事件坑位的初始战力完美击败
    public int countFightResult() {
        if (!isHaveFight()) {// 初始怪兽战力=0.表示不发生战斗，如搜救事件，获得普通奖励和碎片,采集事件有概率不发生战斗
            return WorldConstant.WORLD_EVENT_RESULT_2;// 普通击败
        }
        long myPower = getPower();// 我方的战力
        if (myPower <= getForces()) {
            return WorldConstant.WORLD_EVENT_RESULT_1;// 失败
        } else if (myPower >= getTotalForces()) {
            return WorldConstant.WORLD_EVENT_RESULT_3;// 完美击败
        } else {
            return WorldConstant.WORLD_EVENT_RESULT_2;// 普通击败
        }
    }

    /**
     * 产生伤兵的数量$$损失兵数
     * @return
     */
    public int countSoldierWound() {
        long myPower = getPower();// 我方的战力
        long forces = getForces();// 对方的战力
        int soldier = getSoldier();
        if (forces <= 0) {
            return 0;// 没有战斗不产生伤兵
        }

        double result = 0;
        double tmp = 0;
        double aa = (double) myPower / forces;// 我方战力/对方战力
        if (myPower >= forces) {// 队伍当前兵数*（0.4/(我方实力/敌方实力)^0.4)
            double bb = Math.pow(aa, 0.4);
            tmp = 0.4 / bb;
        } else {// 队伍当前兵数*（1-0.4*(我方实力/敌方实力)^10）
            double bb = Math.pow(aa, 10);
            tmp = 1 - 0.4 * bb;
        }
        result = soldier * tmp;// 产生的伤兵

        List<UserPartner> userPartnerList = PartnerManager.getUserPartnerList(userId, getPartnerArray());
        int skillAdd = WorldManager.countWorldPowerAdd(userPartnerList, SkillConstant.EFFECT_TYPE_107, 0);// 总的减少的百分比
        int worldBossSub = 0;
        if (getLocationId() == WorldConstant.WORLD_EVENT_LOCATION_ID_BOSS){ // 如果是世界boss事件
            // 计算是否有干员技能能兵力损耗降低%
            skillAdd += WorldManager.countWorldPowerAdd(userPartnerList, SkillConstant.EFFECT_TYPE_28, 0);// 总的减少的百分比
            // 损兵固定值减少
            int subSoldier = WorldManager.countWorldPowerAdd(userPartnerList, SkillConstant.EFFECT_TYPE_108, 0);// 固定值
            result = Math.max(0,result - subSoldier);
        }
        double sub = result * skillAdd / 10000;// 减少的数量
        result = result - sub;

        return (int) Math.floor(result);
    }

    // 计算到达事件地点的时间戳
    public long countArriveTime() {
        return getUpdateTime() + getTimeLeft();
    }


    public PBUserWorldTeam.Builder takeInitBuilder() {
        PBUserWorldTeam.Builder sb = super.takeInitBuilder();
        sb.setSoldierWound(countSoldierWound());// 伤兵数量
        return sb;
    }

    public PBUserWorldTeam.Builder takeBuilder() {
        PBUserWorldTeam.Builder sb = super.takeBuilder();
        sb.setSoldierWound(countSoldierWound());// 伤兵数量
        return sb;
    }

    // 生成战报时 获取战斗奖励的字符串
    public String takeFightReward() {
        int fightResult = getResult();// 结果
        if (getLocationId() == WorldConstant.WORLD_EVENT_LOCATION_ID_BOSS){  // 世界Boss的战斗奖励
            List<RewardItem> rewardItemList =  CommonUtils.takeReawrdItemFromStr(getRandomReward());
            return CommonUtils.getRewardString(rewardItemList);
        }
        if (fightResult == WorldConstant.WORLD_EVENT_RESULT_0 || fightResult == WorldConstant.WORLD_EVENT_RESULT_1) {
            return "";// 未战斗，队伍到达前事件过期 或战斗失败
        }

        WorldEvent worldEvent = WorldManager.getWorldEvent(getEventId());
        if (worldEvent == null) {
            return "";
        }
        List<RewardItem> rewardItemList = CommonUtils.takeReawrdItemFromStr(worldEvent.getReward());// 普通奖励

        if (fightResult == WorldConstant.WORLD_EVENT_RESULT_3) {// 完美击败，普通奖励+完美奖励+宝箱奖励
            if (!Tool.isEmpty(worldEvent.getPerfectReward())) {
                CommonUtils.mergeItemList(rewardItemList, CommonUtils.takeReawrdItemFromStr(worldEvent.getPerfectReward()));
            }
            if (!Tool.isEmpty(getBoxReward())) {
                CommonUtils.mergeItemList(rewardItemList, CommonUtils.takeReawrdItemFromStr(getBoxReward()));
            }
        }

        if (!Tool.isEmpty(getRandomReward())) {// 其他的随机奖励。如秘书碎片
            CommonUtils.mergeItemList(rewardItemList, CommonUtils.takeReawrdItemFromStr(getRandomReward()));
        }

        int skillAdd = SkillManager.getSkillMoudleAdd(userId, SkillConstant.EFFECT_TYPE_14, 0);// 大世界探索时城市经验获得增加 固定值 秘书带的 100005
        if (skillAdd > 0) {
            for (RewardItem rewardItem : rewardItemList) {
                if (rewardItem.getItemId() == ItemId.USER_REPU) {
                    long newNum = rewardItem.getItemNum() + skillAdd;
                    rewardItem.setItemNum(newNum);
                }
            }
        }

        return CommonUtils.getRewardString(rewardItemList);
    }

    // 是否临时的行军队列
    public boolean isTmp() {
        if (getTeamId() == WorldConstant.WORLD_TEAM_TMP) {
            return true;
        } else {
            return false;
        }
    }

    // 该队伍出征，是否有发生战斗
    public boolean isHaveFight() {
        if (getTotalForces() > 0) {
            return true;
        } else {
            return false;
        }
    }

    // 该队伍出征，战斗完是否会影响user_world_info 的怪兽等级
    public boolean isChangeMonsterLevel() {
        WorldEvent worldEvent = WorldManager.getWorldEvent(getEventId());
        if (worldEvent.getType() == WorldConstant.WORLD_EVENT_TYPE_5) {// 悬赏事件，雷达提升等级时解锁
            return false;// 悬赏事件，怪兽实力走配置
        }
        if (isHaveFight()) {
            return true;
        } else {
            return false;
        }
    }

    // 计算队伍的到达时间
    public long takeArriveTime() {
        long arriveTime = getUpdateTime() + getTimeLeft() - getReduceTime();
        return arriveTime;
    }
}
